//
// Created by chizuru on 2025/9/19.
//
#pragma once
#include "aop.hpp"
#include <functional>

namespace aop {
    // -----------------------------
    // AutoProxy (CRTP helper)
    // -----------------------------
    template<typename Derived>
    struct AutoProxy {
    protected:
        // bind member to an Advisable (captures this pointer)
        template<typename R, typename... Args>
        static Advisable<R, Args...> bind_to_this(Derived* self, R(Derived::*mf)(Args...)) {
            auto f = [self, mf](Args... args)->R {
                return (self->*mf)(std::forward<Args>(args)...);
            };
            return make_advisable<R, Args...>(std::function<R(Args...)>(std::move(f)));
        }

        // const overload
        template<typename R, typename... Args>
        static Advisable<R, Args...> bind_to_this(const Derived* self, R(Derived::*mf)(Args...) const) {
            auto f = [self, mf](Args... args)->R {
                return (self->*mf)(std::forward<Args>(args)...);
            };
            return make_advisable<R, Args...>(std::function<R(Args...)>(std::move(f)));
        }
    };
}// namespace aop
